home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pico / msspell.c < prev    next >
C/C++ Source or Header  |  1996-03-15  |  13KB  |  483 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: msspell.c,v 4.8 1996/03/15 07:41:11 hubert Exp $";
  3. #endif
  4. /*
  5.  * Program:    msspell.c
  6.  *
  7.  *
  8.  * Thomas Unger
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: unger@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  */
  29.  
  30. #include <windows.h>
  31. #include <stdio.h>
  32. #include "osdep.h"
  33. #include "pico.h"
  34. #include "estruct.h"
  35. #ifdef    SPELLER
  36. #include "edef.h"
  37.  
  38. #pragma pack(1)
  39. #include "msspell.h"
  40. #pragma pack()
  41.  
  42.  
  43.  
  44. extern FILE        *gfDebugFile = NULL;
  45.  
  46.  
  47.  
  48. #ifdef    ANSI
  49.     void chword(char *, char *);
  50.     int  movetoword(char *);
  51. #else
  52.     void chword();
  53.     int  movetoword();
  54. #endif
  55.  
  56.  
  57. #define  NSHLINES  12
  58.  
  59. static char *spellhelp[] = {
  60.   "Spell Check Help",
  61.   " ",
  62.   "\tThe spell checker examines all words in the text.  It then",
  63.   "\toffers each misspelled word for correction while simultaneously",
  64.   "\thighlighting it in the text.  To leave a word unchanged simply",
  65.   "~\thit ~R~e~t~u~r~n at the edit prompt.  If a word has been corrected,",
  66.   "\teach occurrence of the incorrect word is offered for replacement.",
  67.   " ",
  68.   "~\tSpell checking can be cancelled at any time by typing ~^~C (~F~3)",
  69.   "\tafter exiting help.",
  70.   " ",
  71.   "End of Spell Check Help",
  72.   " ",
  73.   NULL
  74. };
  75.  
  76.  
  77. static char *pinespellhelp[] = {
  78.   "Spell Check Help",
  79.   " ",
  80.   "\tThe spell checker examines all words in the text.  It then",
  81.   "\toffers each misspelled word for correction while simultaneously",
  82.   "\thighlighting it in the text.  To leave a word unchanged simply",
  83.   "\thit Return at the edit prompt.  If a word has been corrected,",
  84.   "\teach occurrence of the incorrect word is offered for replacement.",
  85.   " ",
  86.   "\tSpell checking can be cancelled at any time by typing ^C (F3)",
  87.   "\tafter exiting help.",
  88.   " ",
  89.   "End of Spell Check Help",
  90.   " ",
  91.   NULL
  92. };
  93.  
  94.  
  95.  
  96.  
  97. typedef struct {
  98.      HINSTANCE    hSpell;
  99.      WORD    version;
  100.      FARPROC    Version;
  101.      FARPROC    CheckWord;
  102.      FARPROC    GetValidLettersBlock;
  103.      BYTE    validChars[256];
  104. } Spell300;
  105.  
  106. #define SPELL_DLL_NAME        "SPELLCH3.DLL"
  107.  
  108.  
  109. extern HWND        ghTTYWnd;
  110. extern HINSTANCE    ghInstance;
  111.  
  112.  
  113. LRESULT FAR PASCAL __export CWHook (HWND hWnd, UINT uMsg, 
  114.                 WPARAM wParam, LPARAM lParam);
  115. void    showsize (void);
  116.  
  117.  
  118. /*
  119.  * spell() - check for potentially missspelled words and offer them for
  120.  *           correction
  121.  */
  122. spell(f, n)
  123. {
  124.     int        status;
  125.     char    errbuf[128];
  126.     Spell300    speller;
  127.     UINT    errFlag;
  128.     char    wb[NLINE], cb[NLINE];
  129.     CHECKWORD    checkword;
  130.     int        i;
  131.     
  132.         
  133.     if (curwp->w_markp)                /* Clear existing mark. */
  134.     setmark (0, 1);
  135.     setimark(0, 1);
  136.     emlwrite("Checking spelling...");         /* greetings */
  137.  
  138.     
  139.     /*
  140.      * Load speller DLL.
  141.      */
  142.     errFlag = SetErrorMode (SEM_NOOPENFILEERRORBOX);
  143.     speller.hSpell = LoadLibrary (SPELL_DLL_NAME);
  144.     SetErrorMode (errFlag);
  145.     if ((UINT)speller.hSpell < (UINT)HINSTANCE_ERROR) {
  146.     mswin_exec_err_msg ("speller", (int)speller.hSpell, errbuf, 128);
  147.     emlwrite (errbuf);
  148.     return(-1);
  149.     }
  150.     
  151.     speller.Version = GetProcAddress (speller.hSpell, "SPCHK_Version");
  152.     speller.CheckWord = GetProcAddress (speller.hSpell, "SPCHK_CheckWord");
  153.     speller.GetValidLettersBlock = GetProcAddress (speller.hSpell, 
  154.                         "SPCHK_GetValidLettersBlock");
  155.     if (    speller.Version == NULL || 
  156.         speller.CheckWord == NULL || 
  157.         speller.GetValidLettersBlock == NULL) {
  158.     emlwrite ("Speller DLL does not support the correct functions", NULL);
  159.     return (-1);
  160.     }
  161.     speller.version = speller.Version ();
  162.     
  163.     
  164.     /*
  165.      * Get list of valid letters.
  166.      */
  167.     speller.GetValidLettersBlock (&speller.validChars);
  168.     
  169.     
  170.     /*
  171.      * Initialize the checkword structure.
  172.      */
  173.     memset (&checkword, 0, sizeof (CHECKWORD));
  174.     checkword.wSizeOfBlock = sizeof (CHECKWORD);
  175.     checkword.hWndParent = ghTTYWnd;
  176.     checkword.CheckWordOptions = CWO_ALLOWCHANGE | CWO_AUTOSUGGEST | 
  177.         CWO_NOHELP | CWO_USEMAINHOOK | CWO_SENDMSGTOMAINHOOK |
  178.         CWO_CHECKMULTIPLE;
  179.     checkword.fpMainHook = MakeProcInstance ((FARPROC) CWHook, ghInstance);
  180.     checkword.dwCustData = (DWORD) &speller;
  181.     
  182.     gotobob(0, 1);
  183.     checkword.wSizeOfBlock = sizeof (CHECKWORD);
  184.     status = speller.CheckWord (&checkword);
  185.     
  186.     
  187.     FreeProcInstance (checkword.fpMainHook);
  188.     FreeLibrary (speller.hSpell);
  189.     speller.hSpell = NULL;
  190.     speller.Version = NULL;
  191.     speller.CheckWord = NULL;
  192.     emlwrite("Done checking spelling");
  193.     if (curwp->w_markp) {
  194.     markregion (0);
  195.     setmark (0, 1);        /* Clears mark. */
  196.     }
  197.     swapimark (0, 1);
  198.     return (TRUE);
  199. }
  200.  
  201.  
  202. #if  0
  203. void
  204. showsize ()
  205. {
  206.     CHECKWORD    cw;
  207.     int        size;
  208.     char    b[256];
  209.     
  210.     size = 0;
  211.     size += sizeof(cw.wSizeOfBlock);
  212.     wsprintf (b, "wSizeOfBlock %d, size %d\r\n", sizeof(cw.wSizeOfBlock), size);
  213.     OutputDebugString (b);
  214.     size += sizeof(cw.hWndParent);
  215.     wsprintf (b, "hWndParent %d, size %d\r\n", sizeof(cw.hWndParent), size);
  216.     OutputDebugString (b);
  217.     size += sizeof(cw.hWndDlg);
  218.     wsprintf (b, "hWndDlg %d, size %d\r\n", sizeof(cw.hWndDlg), size);
  219.     OutputDebugString (b);
  220.     size += sizeof(cw.CheckWordOptions);
  221.     wsprintf (b, "CheckWordOptions %d, size %d\r\n", sizeof(cw.CheckWordOptions), size);
  222.     OutputDebugString (b);
  223.     size += sizeof(cw.szLanguage);
  224.     wsprintf (b, "szLanguage %d, size %d\r\n", sizeof(cw.szLanguage), size);
  225.     OutputDebugString (b);
  226.     size += sizeof(cw.hCustomDics);
  227.     wsprintf (b, "hCustomDics %d, size %d\r\n", sizeof(cw.hCustomDics), size);
  228.     OutputDebugString (b);
  229.     size += sizeof(cw.NumCustom);
  230.     wsprintf (b, "NumCustom %d, size %d\r\n", sizeof(cw.NumCustom), size);
  231.     OutputDebugString (b);
  232.     size += sizeof(cw.CurCustom);
  233.     wsprintf (b, "CurCustom %d, size %d\r\n", sizeof(cw.CurCustom), size);
  234.     OutputDebugString (b);
  235.     size += sizeof(cw.hDebugLog);
  236.     wsprintf (b, "hDebugLog %d, size %d\r\n", sizeof(cw.hDebugLog), size);
  237.     OutputDebugString (b);
  238.     size += sizeof(cw.hInstance);
  239.     wsprintf (b, "hInstance %d, size %d\r\n", sizeof(cw.hInstance), size);
  240.     OutputDebugString (b);
  241.     size += sizeof(cw.fpMainHook);
  242.     wsprintf (b, "fpMainHook %d, size %d\r\n", sizeof(cw.fpMainHook), size);
  243.     OutputDebugString (b);
  244.     size += sizeof(cw.fpOptionsHook);
  245.     wsprintf (b, "fpOptionsHook %d, size %d\r\n", sizeof(cw.fpOptionsHook), size);
  246.     OutputDebugString (b);
  247.     size += sizeof(cw.lpMainDlg);
  248.     wsprintf (b, "lpMainDlg %d, size %d\r\n", sizeof(cw.lpMainDlg), size);
  249.     OutputDebugString (b);
  250.     size += sizeof(cw.lpOptionsDlg);
  251.     wsprintf (b, "lpOptionsDlg %d, size %d\r\n", sizeof(cw.lpOptionsDlg), size);
  252.     OutputDebugString (b);
  253.     size += sizeof(cw.dwCustData);
  254.     wsprintf (b, "dwCustData %d, size %d\r\n", sizeof(cw.dwCustData), size);
  255.     OutputDebugString (b);
  256.     size += sizeof(cw.dwCustData2);
  257.     wsprintf (b, "dwCustData2 %d, size %d\r\n", sizeof(cw.dwCustData2), size);
  258.     OutputDebugString (b);
  259.     size += sizeof(cw.ToCheck);
  260.     wsprintf (b, "ToCheck %d, size %d\r\n", sizeof(cw.ToCheck), size);
  261.     OutputDebugString (b);
  262.     size += sizeof(cw.Changed);
  263.     wsprintf (b, "Changed %d, size %d\r\n", sizeof(cw.Changed), size);
  264.     OutputDebugString (b);
  265.     size += sizeof(cw.bCurWordChanged);
  266.     wsprintf (b, "bCurWordChanged %d, size %d\r\n", sizeof(cw.bCurWordChanged), size);
  267.     OutputDebugString (b);
  268.     size += sizeof(cw.PrevWord);
  269.     wsprintf (b, "PrevWord %d, size %d\r\n", sizeof(cw.PrevWord), size);
  270.     OutputDebugString (b);
  271.     size += sizeof(cw.wFunctionType);
  272.     wsprintf (b, "wFunctionType %d, size %d\r\n", sizeof(cw.wFunctionType), size);
  273.     OutputDebugString (b);
  274.     size += sizeof(cw.CurPosCheck);
  275.     wsprintf (b, "CurPosCheck %d, size %d\r\n", sizeof(cw.CurPosCheck), size);
  276.     OutputDebugString (b);
  277.     size += sizeof(cw.CurPosChanged);
  278.     wsprintf (b, "CurPosChanged %d, size %d\r\n", sizeof(cw.CurPosChanged), size);
  279.     OutputDebugString (b);
  280.     size += sizeof(cw.CurWord);
  281.     wsprintf (b, "CurWord %d, size %d\r\n", sizeof(cw.CurWord), size);
  282.     OutputDebugString (b);
  283.     size += sizeof(cw.hDic);
  284.     wsprintf (b, "hDic %d, size %d\r\n", sizeof(cw.hDic), size);
  285.     OutputDebugString (b);
  286.     size += sizeof(cw.hIndexBlock);
  287.     wsprintf (b, "hIndexBlock %d, size %d\r\n", sizeof(cw.hIndexBlock), size);
  288.     OutputDebugString (b);
  289.     size += sizeof(cw.lpLoadedBlock);
  290.     wsprintf (b, "lpLoadedBlock %d, size %d\r\n", sizeof(cw.lpLoadedBlock), size);
  291.     OutputDebugString (b);
  292.     size += sizeof(cw.lpIndexBlock);
  293.     wsprintf (b, "lpIndexBlock %d, size %d\r\n", sizeof(cw.lpIndexBlock), size);
  294.     OutputDebugString (b);
  295.     size += sizeof(cw.hWordsBlock);
  296.     wsprintf (b, "hWordsBlock %d, size %d\r\n", sizeof(cw.hWordsBlock), size);
  297.     OutputDebugString (b);
  298.     size += sizeof(cw.dwWordsSize);
  299.     wsprintf (b, "dwWordsSize %d, size %d\r\n", sizeof(cw.dwWordsSize), size);
  300.     OutputDebugString (b);
  301.     size += sizeof(cw.bExpandWordsBlock);
  302.     wsprintf (b, "bExpandWordsBlock %d, size %d\r\n", sizeof(cw.bExpandWordsBlock), size);
  303.     OutputDebugString (b);
  304.     size += sizeof(cw.hIgnoreAll);
  305.     wsprintf (b, "hIgnoreAll %d, size %d\r\n", sizeof(cw.hIgnoreAll), size);
  306.     OutputDebugString (b);
  307.     size += sizeof(cw.lpIgnoreAll);
  308.     wsprintf (b, "lpIgnoreAll %d, size %d\r\n", sizeof(cw.lpIgnoreAll), size);
  309.     OutputDebugString (b);
  310.     size += sizeof(cw.lpCustomDics);
  311.     wsprintf (b, "lpCustomDics %d, size %d\r\n", sizeof(cw.lpCustomDics), size);
  312.     OutputDebugString (b);
  313.     wsprintf (b, "total size %d, %d\n", size, sizeof (CHECKWORD));
  314.     OutputDebugString (b);
  315. }
  316. #endif
  317.  
  318.  
  319.  
  320. LRESULT FAR PASCAL __export 
  321.  
  322. CWHook (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  323. {
  324.     LPCHECKWORD        pCW;
  325.     BOOL        more;
  326.     Spell300        *psp;
  327.     
  328.  
  329.     switch (uMsg) {
  330.     case SPELL_GETNEXT:
  331.     pCW = (LPCHECKWORD) lParam;
  332.     psp = (Spell300 *)pCW->dwCustData;
  333.     more = nextword (pCW->ToCheck, &psp->validChars);
  334.     // update ();
  335.     return (more);
  336.     
  337.     case SPELL_WORDNOTFOUND:
  338.     update ();
  339.     return (0);
  340.     
  341.     case SPELL_WORDCHANGED:
  342.     pCW = (LPCHECKWORD) lParam;
  343.     chword (pCW->ToCheck, pCW->Changed);
  344.     update ();
  345.     return (0);
  346.     
  347.     default:
  348.     return (0);
  349.     }
  350.     return (0);
  351. }
  352.  
  353.  
  354.  
  355.  
  356.  
  357. /* 
  358.  * chword() - change the given word, wp, pointed to by the curwp->w_dot 
  359.  *            pointers to the word in cb
  360.  */
  361. void
  362. chword(wb, cb)
  363.   char *wb;                    /* word buffer */
  364.   char *cb;                    /* changed buffer */
  365. {
  366.     /* Clear region. */
  367.     markregion (0);                /* Clear highlighting. */
  368.     curwp->w_markp = NULL;
  369.     
  370.     ldelete((long) strlen(wb), 0);        /* not saved in kill buffer */
  371.     while(*cb != '\0')
  372.       linsert(1, *cb++);
  373.  
  374.  
  375.  
  376.     curwp->w_flag |= WFEDIT;
  377. }
  378.  
  379.  
  380.  
  381.  
  382. /* 
  383.  * nextword() - Move to next word.
  384.  *
  385.  *    returns:
  386.  *        TRUE upon success
  387.  *        FALSE otherwise
  388.  */
  389. nextword (w, validChar)
  390.   char *w;
  391.   BYTE *validChar;
  392. {
  393.     int      i;
  394.     int      ret  = FALSE;
  395.     int         ll;
  396.     int         olddoto;
  397.     LINE     *olddotp;
  398.     register int   off;                /* curwp offset */
  399.     register LINE *lp;                /* curwp line   */
  400.     char     c;
  401.     
  402.  
  403.     markregion (0);                /* Clear highlighting. */
  404.  
  405.     olddoto = curwp->w_doto;            /* save where we are */
  406.     olddotp = curwp->w_dotp;
  407.     
  408.     /*
  409.      * Advance dot to mark then scan for alphabetical character.
  410.      */
  411.     if (curwp->w_markp) {
  412.     curwp->w_dotp = curwp->w_markp;
  413.     curwp->w_doto = curwp->w_marko;
  414.     }
  415.  
  416.     /*
  417.      * Get line length and check if already at end of line.
  418.      */
  419.     ll =  llength(curwp->w_dotp);
  420.     
  421.     /*
  422.      * Scan throug text for start of a word.
  423.      */
  424.     for (;;) {
  425.     if (curwp->w_doto < ll) {
  426.         c = lgetc(curwp->w_dotp, curwp->w_doto).c;
  427.         if (validChar[c])
  428.         break;
  429.         }
  430.     if (++curwp->w_doto >= ll) {
  431.         /* Move to the next line until we find a line that does not
  432.          * start with the message quote character. */
  433.         do {
  434.         curwp->w_dotp = lforw(curwp->w_dotp);
  435.         if (curwp->w_dotp == curbp->b_linep) 
  436.             goto NoWord;
  437.         ll =  llength(curwp->w_dotp);
  438.         curwp->w_doto = 0;
  439.         c = lgetc(curwp->w_dotp, curwp->w_doto).c;
  440.             } while (Pmaster && Pmaster->quote_str && c == *Pmaster->quote_str);
  441.         }
  442.     }
  443.     
  444.     
  445.     
  446.     /*
  447.      * Scan to next blank.
  448.      */
  449.     curwp->w_markp = curwp->w_dotp;
  450.     curwp->w_marko = curwp->w_doto + 1;
  451.     
  452.     ll =  llength(curwp->w_markp);
  453.     for (;;) {
  454.     c = lgetc(curwp->w_markp, curwp->w_marko).c;
  455.     if (!validChar[c])
  456.         break;
  457.     if (++curwp->w_marko >= ll)
  458.         break;
  459.     }
  460.     
  461.     /*
  462.      * Copy characters between dot and mark into word buffer.
  463.      */
  464.     for (i = curwp->w_doto; i < curwp->w_marko; ++i) 
  465.     *w++ = lgetc(curwp->w_dotp, i).c;
  466.     *w = '\0';
  467.     curwp->w_flag |= WFHARD;
  468.     return (TRUE);
  469.  
  470.     
  471.     /*
  472.      * No word found.  Leave DOT at last word and return FALSE;
  473.      */
  474. NoWord:
  475.     curwp->w_flag |= WFHARD;
  476.     setmark (0, 1);                /* Clears mark. */
  477.     curwp->w_doto = olddoto;
  478.     curwp->w_dotp = olddotp;
  479.     *w = '\0';
  480.     return (FALSE);
  481. }
  482. #endif    /* SPELLER */
  483.